home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
FishMarket 1.0
/
FishMarket v1.0.iso
/
fishies
/
476-500
/
disk_493
/
bbformat
/
lib
/
mytdio.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-05-06
|
5KB
|
193 lines
/*
* MyTDIO.c
*
* Handles a trackdisk RAW read with WORDSYNC.
* I can't get the ETD_RAWREAD to work, so coded one myself. DAV
*/
#include <exec/types.h>
#include <exec/nodes.h>
#include <exec/lists.h>
#include <exec/memory.h>
#include <exec/interrupts.h>
#include <exec/ports.h>
#include <exec/libraries.h>
#include <exec/io.h>
#include <exec/tasks.h>
#include <exec/execbase.h>
#include <exec/devices.h>
#include <devices/trackdisk.h>
#include <hardware/custom.h>
#include <hardware/cia.h>
#include <hardware/intbits.h>
#include <hardware/adkbits.h>
#include <hardware/dmabits.h>
#include <resources/disk.h>
#define __NO_PRAGMAS
#include <functions.h>
#define CIAF_DSKSELALL (CIAF_DSKSEL3 | CIAF_DSKSEL2\
| CIAF_DSKSEL1 | CIAF_DSKSEL0)
#ifndef NUMHEADS
#define NUMHEADS 2
#endif
extern struct Custom custom;
extern struct CIA ciaa, ciab;
/* Above doesn't seem to work with Aztec, small data model, so ... */
#define CUSTOMADD ((struct Custom *)0xdff000)
#define CIAAADD ((struct CIA *)0xbfe001)
#define CIABADD ((struct CIA *)0xbfd000)
/*
* Disable/Enable interrupts at the CPU
*/
static APTR sysStack;
static ULONG oldSR;
cpuDisable()
{
oldSR = SetSR(0x700L,0x700L);
sysStack = SuperState();
}
cpuEnable()
{
if(sysStack) UserState(sysStack);
SetSR(oldSR,0x700L);
}
/* make a special read request up */
MyTDIO(struct IOExtTD *tdreq)
{
struct Custom *pcustom = CUSTOMADD; /*&custom;*/
struct CIA *pciaa = CIAAADD; /*&ciaa;*/
struct CIA *pciab = CIABADD; /*&ciab;*/
UWORD command;
ULONG actual,length,offset;
APTR data;
UBYTE flags;
int drive,head;
UWORD dsklenw;
long timeout;
struct IOStdReq *req = (struct IOStdReq *) tdreq;
if(!(req->io_Command == ETD_RAWREAD || req->io_Command == TD_RAWREAD)) {
req->io_Error = 100;
return;
}
/* our request - local copy parameters */
command = req->io_Command;
flags = req->io_Flags;
actual = req->io_Actual; /* SPECIAL - expect drive unit # here */
length = req->io_Length;
data = req->io_Data;
offset = req->io_Offset; /* Track (not cyl) */
drive = actual;
head = offset % (NUMSECS*TD_SECTOR);
/* Seek to track */
req->io_Offset = offset * (NUMSECS*TD_SECTOR);
req->io_Command = TD_SEEK;
DoIO((struct IORequest *)req);
if(req->io_Error != 0) {
req->io_Error = 101;
return;
}
/* Do raw - read magic */
cpuDisable();
pcustom->dmacon = DMAF_SETCLR | DMAF_DISK | DMAF_MASTER;
/* turn OFF bits - not GCR, and no pre-comp. for now */
pcustom->adkcon = ADKF_PRECOMP0|ADKF_PRECOMP1|ADKF_MSBSYNC|ADKF_WORDSYNC;
/* turn ON bits - mfm */
pcustom->adkcon = ADKF_SETCLR|ADKF_WORDSYNC|ADKF_MFMPREC|ADKF_FAST;
/* turn ON wordsync if required */
if(flags & IOTDF_WORDSYNC)
pcustom->adkcon = ADKF_SETCLR|ADKF_WORDSYNC;
pcustom->dsksync = 0x4489;
pcustom->dsklen = DSKDMAOFF; /* 0x4000 */
pcustom->dskpt = data;
dsklenw = 0x8000 | ((length >> 1) & 0x3fff);
pciab->ciaprb &= ~CIAF_DSKMOTOR; /* ensure motor on */
if(drive == 0)
pciab->ciaprb &= ~CIAF_DSKSEL0;
else if(drive == 1)
pciab->ciaprb &= ~CIAF_DSKSEL1;
else if(drive == 2)
pciab->ciaprb &= ~CIAF_DSKSEL2;
else if(drive == 3)
pciab->ciaprb &= ~CIAF_DSKSEL3;
if(head == 0)
pciab->ciaprb &= ~CIAF_DSKSIDE;
else
pciab->ciaprb |= CIAF_DSKSIDE;
pcustom->dsklen = dsklenw; /* first write */
timeout = 0;
while(pciaa->ciapra & CIAF_DSKRDY) { /* wait for ready */
if(++timeout > 1000000L) {
pcustom->dsklen = DSKDMAOFF;
pciab->ciaprb |= (CIAF_DSKSELALL);
cpuEnable();
req->io_Error = 102;
return; /* timed out waiting for ready */
}
}
if(flags & IOTDF_INDEXSYNC) {
timeout = pciab->ciaicr;
timeout = 0;
while(!(pciab->ciaicr & CIAICRF_FLG)) { /* wait for index pls */
if(++timeout > 1000000L) {
pcustom->dsklen = DSKDMAOFF;
pciab->ciaprb |= (CIAF_DSKSELALL);
cpuEnable();
req->io_Error = 103;
return; /* timed out waiting for index */
}
}
}
pcustom->intena = INTF_SETCLR | INTF_DSKBLK;
pcustom->intreq = INTF_DSKBLK; /* clear pending DMA-done */
pcustom->dsklen = dsklenw; /* second write - start DMA*/
timeout = 0;
while(!(pcustom->intreqr & INTF_DSKBLK)) { /* wait for DMA done */
if(++timeout > 1000000L) {
pcustom->dsklen = DSKDMAOFF;
pciab->ciaprb |= (CIAF_DSKSELALL);
cpuEnable();
req->io_Error = 104;
return; /* timed out waiting for DMA */
}
}
pciab->ciaprb |= (CIAF_DSKSELALL);
pcustom->dsklen = DSKDMAOFF;
pcustom->intreq = INTF_DSKBLK; /* clear DMA-done */
cpuEnable();
req->io_Error = 0;
return;
}